package com.im.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.im.constant.CommonConstant;
import com.im.entity.ImGroup;
import com.im.entity.ImUser;
import com.im.entity.dto.UpdatePasswordDTO;
import com.im.entity.dto.UserLoginDTO;
import com.im.entity.dto.UserRegisterDTO;
import com.im.entity.vo.UserInfoVO;
import com.im.mapper.ImUserMapper;
import com.im.service.IImUserService;
import com.im.utils.*;
import com.im.utils.Redis.RedisIdGenerator;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author im
 * @since 2025-01-30
 */
@Service
public class ImUserServiceImpl extends ServiceImpl<ImUserMapper, ImUser> implements IImUserService {

    @Autowired
    private RedisIdGenerator redisIdGenerator;
    @Autowired
    private TokenUtil tokenUtil;
    @Autowired
    private FileUploadUtil fileUploadUtil;
    /**
     * 用户登录
     * @param userLoginDTO 用户登录信息
     * @return 用户信息+token
     */
    @Override
    public UserInfoVO login(UserLoginDTO userLoginDTO) {
        //两种策略 一种电话登录，一种邮箱登录
        LambdaQueryWrapper<ImUser> imUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (userLoginDTO.getLoginType().equals("phone")){
            imUserLambdaQueryWrapper.eq(ImUser::getPhone,userLoginDTO.getPhone());
        }else if (userLoginDTO.getLoginType().equals("email")){
            imUserLambdaQueryWrapper.eq(ImUser::getEmail,userLoginDTO.getEmail());
        }else{
            throw new RuntimeException("登录类型错误");
        }
        //查询用户是否存在
        ImUser user = this.baseMapper.selectOne(imUserLambdaQueryWrapper);
        if (user==null){
            throw new RuntimeException("用户不存在");
        }
        //验证密码
        if (!PasswordUtil.matches(userLoginDTO.getPassword(),user.getPassword())){
            throw new RuntimeException("账户或密码错误");
        }
        //判断是否被封禁
        if (user.getStatus()== CommonConstant.FALSE){
            throw new RuntimeException("账户被封禁,请联系管理员");
        }
        //生成 Token
        String token =tokenUtil.generateToken(user.getUserId(),user.getUsername(),user.getPhone());
        //返回用户信息
        UserInfoVO userInfoVO = BeanCopyUtils.copyObject(user, UserInfoVO.class);

        userInfoVO.setToken(token);
        return userInfoVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserInfoVO register(UserRegisterDTO userRegisterDTO) {
        //后续放redis判断
        ImUser imUser = this.baseMapper.selectOne(new LambdaQueryWrapper<ImUser>()
                .eq(ImUser::getPhone, userRegisterDTO.getPhone()));
        if (imUser != null) {
            throw new RuntimeException("手机号已注册，请直接登录");
        }
        // 3. 创建新用户
        ImUser newUser = new ImUser();
        BeanUtils.copyProperties(userRegisterDTO, newUser);
        // 4. 设置加密密码
        newUser.setPassword(PasswordUtil.encode(userRegisterDTO.getPassword()));
        // 5. 生成唯一用户 ID（redis生成)
        newUser.setUserId(redisIdGenerator.generateUserId());
        // 6. 设置默认头像() todo 后续根据用户名称生成一个默认头像
        newUser.setAvatar(CommonConstant.DEFAULT_AVATAR);
        // 6. 存入数据库
        this.baseMapper.insert(newUser);
        // 7. 生成 Token
        String token = tokenUtil.generateToken(newUser.getUserId(), newUser.getUsername(), newUser.getPhone());
        // 8. 构造 VO 返回
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(newUser, userInfoVO);
        userInfoVO.setToken(token);
        return userInfoVO;
    }

    /**
     * 根据userId获取用户信息
     * @param userId
     * @return
     */
    @Override
    public UserInfoVO getUserById(Integer userId) {
        ImUser user = this.baseMapper.selectOne(new LambdaQueryWrapper<ImUser>().eq(ImUser::getUserId, userId));
        //返回用户信息
        return BeanCopyUtils.copyObject(user, UserInfoVO.class);
    }

    @Override
    @Transactional
    public UserInfoVO updateUsername(Long userId, String nickname) {
        LambdaUpdateWrapper<ImUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ImUser::getId, userId).set(ImUser::getNickname, nickname);
        this.baseMapper.update(null, updateWrapper);
        // 获取更新后的用户信息
        ImUser updatedUser = this.baseMapper.selectById(userId);
        return BeanCopyUtils.copyObject(updatedUser, UserInfoVO.class);
    }

    @Override
    public void updatePassword(Long userId, UpdatePasswordDTO passwordDTO) {
        ImUser user = this.baseMapper.selectById(userId);
        if (!PasswordUtil.matches(passwordDTO.getOldPassword(), user.getPassword())) {
            throw new RuntimeException("旧密码错误");
        }
        String newPasswordHash = PasswordUtil.encode(passwordDTO.getNewPassword());
        user.setPassword(newPasswordHash);
        this.baseMapper.updateById(user);
    }

    @Override
    public String updateAvatar(Long userId, MultipartFile file) {
        String avatarUrl = fileUploadUtil.upload(file);
        this.baseMapper.update(null, new LambdaUpdateWrapper<ImUser>()
                .eq(ImUser::getId, userId).set(ImUser::getAvatar, avatarUrl));
        return avatarUrl;
    }


}
